/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Application.Elements;

import Application.CheckResetSimulate;
import Application.UnstableException;

import java.util.List;
import java.util.ArrayList;
/**
 * Element alaposztaly, amibol a tobbi elementet kell szarmaztatni.
 * A legtobb metodus ugyan meg van irva, de a megjelolteket lehet Override-olni,
 * a simulate()-et kotelezo.
 * @author Stikmann
 */
public abstract class Element implements CheckResetSimulate{

    /**
     * Ez egy raragasztott dolog, a modellnek nem resze, csak a kiirasokat
     * konnyiti meg, a controllernek szol. Kivulrol allitando.
     */
    public String name="";


    /**
     * Bemenetek listaja.
     */
    public List<Element> inputs;

    /**
     * Aktuális kimenet
     */
    protected boolean out;
    /**
     * Ezt a metodust mindenkepp felul kell irnia az implementalo osztalyoknak,
     * mert ez a mukodesuk lenyege. Ez a metodus ami a bemenetek lekerdezesevel
     * beallitja a kapu kimeneti erteket.
     * @return Ha valtozott a kimenet, true, egyebkent false
     */
    abstract public boolean simulate() throws UnstableException;

    public Element(){
        inputs=new ArrayList();
    }

    @Override
    public String toString() {
        return (name==null?"":name+":")+getClass().getSimpleName()+"@"+Integer.toHexString(hashCode());
    }

    /**
     * Leellenorzi, hogy a kapu helyesen van-e kotve. Ebben az osztalyban a
     * leggyakoribb kaputipusra, a tobb-bemeneture (legalabb 2) ellenorzunk.
     * @return Ha nincs hiba, null, egyebkent a hibauzenet.
     */
    public String check(){
        //a legtobb logikai kapunak tobb mint 1 bemenet kell
        //ahol nem, Override.
        if (inputs.size()<2){
            return "Ennek a kapunak legalabb ket bemenet kell, "+inputs.size()+" van neki adva.";
        }
        else
            return null;
    }

    /**
     * Alaphelyzetbe allitja a kaput
     */
    public void reset(){
        out=false;
    }

    /**
     * Lekerdezi a kapu kimenetet
     * @return A kimenet erteke.
     */
    public boolean getOut(){
        return out;
    }

    /**
     * Hozzakoti a parameterul kapott kapu kimenetet ennek a bemenetere.
     * @param mihez A kapu aminek a kimenetet ehhez a kapuhoz kotjuk.
     */
    public void connectTo(Element mihez){
        inputs.add(mihez);
    }
}
